import { forwardRef, useEffect, useImperativeHandle, useMemo } from 'react';
import {commonLang} from '@inbiz/utils'
import moment, { Moment } from 'moment';
import { connect, useField, mapProps } from '@formily/react';
import { Field } from '@formily/core';
import { ConfigProvider, DatePicker } from 'antd';
import { GlobalRegistry } from '@inbiz/core';
import { getMessage, TextWidget } from '@inbiz/react';
import { inbiz } from '@inbiz/render';
import { useEvents } from '@inbiz/utils';
import { defaultProps } from '../../designer/schema';
import api from './api';
import './style.less';


const { RangePicker } = DatePicker;
type IProps = {
  value?: any;
  callBackEvents?: {
    onBeforeChange?: (v: string) => boolean;
  };
  onChange?: any;
  formatValue?: [Moment, Moment];
  readOnly?: boolean;
  disabled?: boolean;
  viewMode?: string;
  emit?: {
    /* 弹出日历和关闭日历 */
    (type: 'onOpenChange', value?: [Moment, Moment]): void;
  };
  inbiz: inbiz;
} & typeof defaultProps;


const EformDateRangePickerContent = forwardRef((props: IProps, ref) => {
  // 基础数据
  const { callBackEvents, format, emit, viewMode, ...other } = props;
  const [configEvents] = useEvents(props.callBackEvents, props.emit);
  const field = useField<Field>();
  // ref
  useImperativeHandle(
    ref,
    () => ({
      ...api(configEvents, props),
    }),
    [props.value],
  );
  // useEffect
  useEffect(() => {
    // 验证是否满足 允许小于当前时间，最小值，最大值
    field.setValidatorRule('validator', (value: any, rule: any, ctx: any) => {
      if (!value) {
        return true;
      }
      const format = ctx.field.componentProps.format;
      // 是否允许小于当前时间

      const validValue = [
        {
          indexV: 's',
          accurate: 'second',
          format: 'YYYY-MM-DD HH:mm:ss',
        },
        {
          indexV: 'm',
          accurate: 'minute',
          format: 'YYYY-MM-DD HH:mm',
        },
        {
          indexV: 'H',
          accurate: 'hour',
          format: 'YYYY-MM-DD HH',
        },
        {
          indexV: 'D',
          accurate: 'day',
          format: 'YYYY-MM-DD',
        },
        {
          indexV: 'M',
          accurate: 'month',
          format: 'YYYY-MM',
        },
        {
          indexV: 'Y',
          accurate: 'year',
          format: 'YYYY',
        },
      ];
      const timeArr = ['s', 'm', 'H', 'D', 'M', 'Y'];
      let nowIndex = 's';
      for (let index = 0; index < timeArr.length; index++) {
        if (format.indexOf(timeArr[index]) !== -1) {
          nowIndex = timeArr[index];
          break;
        }
      }
      let accurate = validValue.filter((item) => {
        return item.indexV === nowIndex;
      })[0].accurate;
      if (!ctx.field.componentProps.allowBeforeNow) {
        if (
          (value[0] && moment(value[0]) < moment()?.startOf(accurate as any)) ||
          (value[1] && moment(value[1]) < moment()?.startOf(accurate as any))
        ) {
          return <TextWidget>EformDateRangePicker.validate.DateNotAllowSmallThanNow</TextWidget>;
        }
      }

      // 最小值
      if (ctx.field.componentProps.min) {
        for (let i = 0; i < validValue.length; i++) {
          if (format?.indexOf(validValue[i].indexV) != -1) {
            // 开始时间
            if (
              value[0] &&
              moment(value[0]) <
              moment(ctx.field.componentProps.min).startOf(validValue[i].accurate as any)
            ) {
              return (
                <>
                  <TextWidget>EformDateRangePicker.validate.dateCannotLessThan</TextWidget>
                  {moment(ctx.field.componentProps.min).format(props.format)}
                </>
              );
            }
            // 结束时间
            if (
              value[1] &&
              moment(value[1]) <
              moment(ctx.field.componentProps.min).startOf(validValue[i].accurate as any)
            ) {
              return (
                <>
                  <TextWidget>EformDateRangePicker.validate.dateCannotLessThan</TextWidget>
                  {moment(ctx.field.componentProps.min).format(props.format)}
                </>
              );
            }
          }
        }
      }
      // 最大值
      if (ctx.field.componentProps.max) {
        for (let i = 0; i < validValue.length; i++) {
          if (format?.indexOf(validValue[i].indexV) != -1) {
            // 开始时间
            if (
              value[0] &&
              moment(value[0]) >
              moment(ctx.field.componentProps.max).endOf(validValue[i].accurate as any)
            ) {
              return (
                <>
                  <TextWidget>EformDateRangePicker.validate.dateCannotMoreThan</TextWidget>
                  {moment(ctx.field.componentProps.max).format(props.format)}
                </>
              );
            }
            // 结束时间
            if (
              value[1] &&
              moment(value[1]) >
              moment(ctx.field.componentProps.max).endOf(validValue[i].accurate as any)
            ) {
              return (
                <>
                  <TextWidget>EformDateRangePicker.validate.dateCannotMoreThan</TextWidget>
                  {moment(ctx.field.componentProps.max).format(props.format)}
                </>
              );
            }
          }
        }
      }
      return true;
    });
  }, []);

  // 所有方法
  // 处理日期 （将获取的用&符号连接的日期转为[Moment, Moment]）
  const formatValue = useMemo(() => {
    if (props.value) {
      if (Array.isArray(props.value)) {
        if (moment.isMoment(props.value[0] || props.value[1])) {
          return props.value;
        } else {
          return [0, 1].map((_, index) => {
            return props.value[index] ? moment(props.value[index]) : undefined;
          });
        }
      } else {
        return [];
      }
    } else {
      return [];
    }
  }, [props.value]);

  const onChange = (value: any) => {
    value
      ? props.onChange([moment(value[0]), moment(value[1])])
      : props.onChange(null);
  };

  //弹出日历和关闭日历
  const onOpenChange = () => {
    props.emit?.('onOpenChange', props.value);
  };
  //index：0-本周 1-本月 2-本季 3-本年
  function selectDateRange(index: number) {
    var now = new Date(); //当前日期
    var nowDayOfWeek = now.getDay() === 0 ? 7 : now.getDay(); //今天本周的第几天
    var nowDay = now.getDate(); //当前日
    var nowMonth = now.getMonth(); //当前月
    var nowYear = now.getFullYear(); //当前年
    // nowYear += (nowYear < 2000) ? 1900 : 0;
    if (index == 0) {
      // 本周开始日期
      var weekStartDate = new Date(nowYear, nowMonth, nowDay - nowDayOfWeek + 1);
      var startweek = moment(weekStartDate);
      // 本周停止日期
      var weekEndDate = new Date(nowYear, nowMonth, nowDay + (6 - nowDayOfWeek + 1));
      var endweek = moment(weekEndDate);
      onChange([startweek, endweek]);
    } else if (index == 1) {
      // 本月
      // 本月开始日期
      var monthStartDate = new Date(nowYear, nowMonth, 1);
      var startmonth = moment(monthStartDate);
      // 本月开始日期
      var monthEndDate = new Date(nowYear, nowMonth, getMonthDays(nowMonth));
      var endmonth = moment(monthEndDate);

      onChange([startmonth, endmonth]);
    } else if (index == 2) {
      // 本季度
      var quarterStartMonth = 0;
      if (nowMonth < 3) {
        quarterStartMonth = 0;
      }
      if (2 < nowMonth && nowMonth < 6) {
        quarterStartMonth = 3;
      }
      if (5 < nowMonth && nowMonth < 9) {
        quarterStartMonth = 6;
      }
      if (nowMonth > 8) {
        quarterStartMonth = 9;
      }
      // 本季开始日期
      var quarterStartDate = new Date(nowYear, quarterStartMonth, 1);
      var startquarter = moment(quarterStartDate);
      // 本季结束日期
      var quarterEndMonth = quarterStartMonth + 2;
      var quarterStartDate = new Date(nowYear, quarterEndMonth, getMonthDays(quarterEndMonth));
      var endquarter = moment(quarterStartDate);

      onChange([startquarter, endquarter]);
    } else if (index == 3) {
      // 本年
      var startyear = moment(new Date(nowYear, 0, 1));
      var endyear = moment(new Date(nowYear, 11, 31));

      onChange([startyear, endyear]);
    }
  }

  // 获得某月的天数
  function getMonthDays(month: any) {
    var nowYear = new Date().getFullYear();
    var monthStartDate = new Date(nowYear, month, 1) as unknown as number;
    var monthEndDate = new Date(nowYear, month + 1, 1) as unknown as number;
    var days = (monthEndDate - monthStartDate) / (1000 * 60 * 60 * 24);
    return days;
  }
 let to=props.value?getMessage('EformDateRangePicker.to'):''
 const locale = useMemo(() => {
  const _lang = GlobalRegistry.getDesignerLanguage();
  return commonLang[_lang?.toLocaleLowerCase()?.replace('-', '_') as keyof typeof commonLang || 'zh_cn'];
}, [GlobalRegistry.getDesignerLanguage()]);
  return (
    <ConfigProvider locale={locale}>
    {viewMode=='look'?(props.value?.[0]&&props.value?.[1])!=null?(formatValue[0].format(props.format)+to+formatValue[1].format(props.format)):'':
        <>
          {props.dateQuickChoose == true &&
            !props.readOnly &&
            !props.disabled &&
            !props.inbiz.browser.designer ? (
            <ul className="edoc2date-range-list">
              <li
                className="item"
                onClick={() => {
                  selectDateRange(0);
                }}
              >
                <TextWidget>EformDateRangePicker.week</TextWidget>
              </li>
              <li
                className="item"
                onClick={() => {
                  selectDateRange(1);
                }}
              >
                <TextWidget>EformDateRangePicker.month</TextWidget>
              </li>
              <li
                className="item"
                onClick={() => {
                  selectDateRange(2);
                }}
              >
                <TextWidget>EformDateRangePicker.season</TextWidget>
              </li>
              <li
                className="item"
                onClick={() => {
                  selectDateRange(3);
                }}
              >
                <TextWidget>EformDateRangePicker.year</TextWidget>
              </li>
            </ul>
          ) : null}
          <RangePicker
            {...other}
            className={'eformDateRangePicker'}
            // getPopupContainer={(triggerNode) => triggerNode.parentElement || document.body}
            dropdownClassName="clearSpaceOccupation"
            inputReadOnly={true}
            disabled={props.readOnly || props.disabled}
            placeholder={[props.startPlaceholder, props.endPlaceholder]}
            value={formatValue as [Moment, Moment]}
            showTime={
              props.format?.indexOf('s') != -1 ||
                props.format?.indexOf('m') != -1 ||
                props.format?.indexOf('H') != -1
                ? { format: props.format?.split(' ')[1] }
                : false
            }
            picker={
              props.format === 'YYYY' ? 'year' : props.format?.indexOf('D') != -1 ? 'date' : 'month'
            }
            onChange={onChange}
            onOpenChange={onOpenChange}
            format={props.format}
          />
        </>
      }

    </ConfigProvider>

  );
});
EformDateRangePickerContent.displayName = 'EformDateRangePickerContent';

(
  EformDateRangePickerContent as typeof EformDateRangePickerContent &
  IDefaultValueFormat<typeof defaultProps>
).originValueFormat = (value: any, props: object) => {
  return value && value[0] && value[1] && [new Date(value[0]), new Date(value[1])];
};

(
  EformDateRangePickerContent as typeof EformDateRangePickerContent &
  IDefaultValueFormat<typeof defaultProps>
).defaultValueFormat = (props): any => {
  var defaultValueArr = [];
  if (props.startDefaultValueType == 'customDefaultValue') {
    defaultValueArr[0] = props.startCustomDefaultValue
      ? new Date(props.startCustomDefaultValue)
      : props.startCustomDefaultValue;
  } else {
    if (props.startVariableDefaultValue == 'nowTime') {
      defaultValueArr[0] = new Date();
    }
  }
  if (props.endDefaultValueType == 'customDefaultValue') {
    defaultValueArr[1] = props.endCustomDefaultValue
      ? new Date(props.endCustomDefaultValue)
      : props.endCustomDefaultValue;
  } else {
    if (props.endVariableDefaultValue == 'nowTime') {
      defaultValueArr[1] = new Date();
    }
  }
  return defaultValueArr;
};

export default connect(
  EformDateRangePickerContent,
  mapProps((props: IProps) => {
    const others = props;
    others.startPlaceholder = getMessage(props.startPlaceholder);
    others.endPlaceholder = getMessage(props.endPlaceholder);
    return { ...others };
  }),
);

export type { IProps };
